#ifndef __tenacitas_log__text_file__h__
#define __tenacitas_log__text_file__h__


// =============================================================================
/** @file */

// =============================================================================
/** todo */

// =============================================================================
//                                 C++ Headers
#include <string>
#include <cstdint>
#include <thread>
#include <sstream>
#include <fstream>
#include <memory>
#include <chrono>

// =============================================================================
//                                 3rds Headers

// =============================================================================
//                                 Our Headers
#include "level.h"

// =============================================================================
//                                 Namespaces
using namespace std;

// =============================================================================
//                                 Macro Contants
/** */

// =============================================================================
//                                 Macro Commands
/** */


/** namespace of the organization */
namespace tenacitas {
    namespace log {

        // =========================== Typedefs ===========================

        // ============================ Pre-Declarations ==================

        // ============================ Attributes ========================
        /** */

        // ============================ Functions =========================
        /** */

        // ============================ Classes ===========================


        /** */
        class text_file_printer_factory;

        /**

         */
        class text_file_printer {

            //    text_file_printer - Friends
            
            /** */
            friend class text_file_printer_factory;

        public:

            //    text_file_printer - Public Internal Types

            /** */
            typedef std::shared_ptr<text_file_printer> ptr;

            //    text_file_printer - Public Constructors
            
            /** */
            text_file_printer( const std::string & p_dir_log,
                               const std::string & p_pgm_name,
                               int64_t p_pid,
                               std::thread::id p_th_id );
            
            /** not allowed */
            text_file_printer( const text_file_printer & ) = delete;

            //    text_file_printer - Public Processors

            /** */
            template <typename t_data>
            void write ( const t_data & p_data ) {
                ( *m_file ) << p_data;
            }

            /** */
            void new_line( level p_level, const char * p_file,
                           const char * p_function, int64_t p_line );
            
            //    text_file_printer - Public Operators
            
            /** */
            text_file_printer & operator = ( const text_file_printer & ) = delete;

        private:

            //    text_file_printer - Private Attributes

            /** */
            std::shared_ptr<ofstream> m_file;
        };

        /** */
        class text_file_printer_factory {
        public:

            //    text_file_printer_factory - Public Internal Types

            /** */
            typedef std::shared_ptr<text_file_printer_factory> ptr;

            /** */
            typedef text_file_printer printer;

            /** */
            typedef text_file_printer::ptr printer_ptr;

            //    text_file_printer_factory - Public Constructors
            
            /** */
            text_file_printer_factory( const std::string & p_dir_log,
                                       const std::string & p_pgm_name,
                                       int64_t p_pid );

            /** not allowed */
            text_file_printer_factory( const text_file_printer_factory & ) =
                delete; 

            //    text_file_printer_factory - Public Processors
            
            /** */
            printer_ptr create( std::thread::id p_th_id ) {
                return printer_ptr( new printer( m_dir_log, m_pgm_name,
                                                 m_pid, p_th_id ) ); 
            }

            //    text_file_printer_factory - Public Operators
            
            /** not allowed */
            text_file_printer_factory &
            operator = ( const text_file_printer_factory & ) = delete;  

        private:

            //    text_file_printer_factory - Private Attributes
            
            /** */
            std::string m_dir_log;

            /** */
            std::string m_pgm_name;

            /** */
            int64_t m_pid;
        };
    }
}


// =============================================================================
//                     I M P L E M E N T A T I O N
// =============================================================================

using namespace tenacitas::log;


#endif
